<template>
  <div style="display: flex;">
    <canvas width="500" height="500" ref="canvas" style="border: 1px solid silver;"></canvas>
    <div style="margin-right: 100px;"></div>
    <div style="width: 300px;">
      <table class="TransformNCamera">
        <colgroup style="min-width: 100px;"></colgroup>
        <colgroup></colgroup>
        <colgroup></colgroup>
        <colgroup></colgroup>
        <thead>
        <tr>
          <th>key</th>
          <th>x(r)</th>
          <th>y(g)</th>
          <th>z(b)</th>
        </tr>
        </thead>
        <tbody>
        <tr>
          <th>transform</th>
          <th colspan="3"></th>
        </tr>
        <tr>
          <td>rotate</td>
          <td>
            <input type="number" :min="-180" :max="180" v-model.number="config.rotate[0]">
            <input type="range" :min="-180" :max="180" v-model.number="config.rotate[0]">
          </td>
          <td>
            <input type="number" :min="-180" :max="180" v-model.number="config.rotate[1]">
            <input type="range" :min="-180" :max="180" v-model.number="config.rotate[1]">
          </td>
          <td>
            <input type="number" :min="-180" :max="180" v-model.number="config.rotate[2]">
            <input type="range" :min="-180" :max="180" v-model.number="config.rotate[2]">
          </td>
        </tr>
        <tr>
          <td>translate</td>
          <td>
            <input type="number" min="-30" max="30" step="0.001" v-model.number="config.translate[0]">
            <input type="range" min="-30" max="30" step="0.001" v-model.number="config.translate[0]">
          </td>
          <td>
            <input type="number" min="-30" max="30" step="0.001" v-model.number="config.translate[1]">
            <input type="range" min="-30" max="30" step="0.001" v-model.number="config.translate[1]">
          </td>
          <td>
            <input type="number" min="-30" max="30" step="0.001" v-model.number="config.translate[2]">
            <input type="range" min="-30" max="30" step="0.001" v-model.number="config.translate[2]">
          </td>
        </tr>
        <tr>
          <td>scale</td>
          <td>
            <input type="number" min="0.5" max="1.5" step="0.1" v-model.number="config.scale[0]">
            <input type="range" min="0.5" max="1.5" step="0.1" v-model.number="config.scale[0]">
          </td>
          <td>
            <input type="number" min="0.5" max="1.5" step="0.1" v-model.number="config.scale[1]">
            <input type="range" min="0.5" max="1.5" step="0.1" v-model.number="config.scale[1]">
          </td>
          <td>
            <input type="number" min="0.5" max="1.5" step="0.1" v-model.number="config.scale[2]">
            <input type="range" min="0.5" max="1.5" step="0.1" v-model.number="config.scale[2]">
          </td>
        </tr>
        <tr>
          <th>camera</th>
          <th colspan="3"></th>
        </tr>
        <!--        <tr>-->
        <!--          <td>move camera</td>-->
        <!--          <td>-->
        <!--            <button @click="movCam([0,1,0])">↑</button>-->
        <!--            <button @click="movCam([0,-1,0])">↓</button>-->
        <!--            <button @click="movCam([-1,0,0])">←</button>-->
        <!--            <button @click="movCam([1,0,0])">→</button>-->
        <!--            <button @click="movCam([0,0,1])">↖</button>-->
        <!--            <button @click="movCam([0,0,-1])">↘</button>-->
        <!--          </td>-->
        <!--        </tr>-->
        <tr>
          <td>move</td>
          <td>
            <input type="number" min="0" max="360" step="1" v-model.number="eyeEuler[0]">
            <input type="range" min="0" max="360" step="1" v-model.number="eyeEuler[0]">
          </td>
          <td>
            <input type="number" min="0" max="360" step="1" v-model.number="eyeEuler[1]">
            <input type="range" min="0" max="360" step="1" v-model.number="eyeEuler[1]">
          </td>
          <td>
            <input type="number" min="0" max="360" step="1" v-model.number="eyeEuler[2]">
            <input type="range" min="0" max="360" step="1" v-model.number="eyeEuler[2]">
          </td>
        </tr>
        <tr>
          <td>position</td>
          <td>
            <input type="number" min="-50" max="50" step=".01" v-model.number="config.eyePos[0]">
            <input type="range" min="-50" max="50" step=".01" v-model.number="config.eyePos[0]">
          </td>
          <td>
            <input type="number" min="-50" max="50" step=".01" v-model.number="config.eyePos[1]">
            <input type="range" min="-50" max="50" step=".01" v-model.number="config.eyePos[1]">
          </td>
          <td>
            <input type="number" min="-50" max="50" step=".01" v-model.number="config.eyePos[2]">
            <input type="range" min="-50" max="50" step=".01" v-model.number="config.eyePos[2]">
          </td>
        </tr>
        <tr>
          <td>looking at</td>
          <td>
            <input type="number" min="-10" max="10" step=".1" v-model.number="config.eyeCenter[0]">
            <input type="range" min="-10" max="10" step=".1" v-model.number="config.eyeCenter[0]">
          </td>
          <td>
            <input type="number" min="-10" max="10" step=".1" v-model.number="config.eyeCenter[1]">
            <input type="range" min="-10" max="10" step=".1" v-model.number="config.eyeCenter[1]">
          </td>
          <td>
            <input type="number" min="-10" max="10" step=".1" v-model.number="config.eyeCenter[2]">
            <input type="range" min="-10" max="10" step=".1" v-model.number="config.eyeCenter[2]">
          </td>
        </tr>
        <tr>
          <td>up direction</td>
          <td>
            <input type="number" min="-10" max="10" step=".1" v-model.number="config.eyeTop[0]">
            <input type="range" min="-10" max="10" step=".1" v-model.number="config.eyeTop[0]">
          </td>
          <td>
            <input type="number" min="-10" max="10" step=".1" v-model.number="config.eyeTop[1]">
            <input type="range" min="-10" max="10" step=".1" v-model.number="config.eyeTop[1]">
          </td>
          <td>
            <input type="number" min="-10" max="10" step=".1" v-model.number="config.eyeTop[2]">
            <input type="range" min="-10" max="10" step=".1" v-model.number="config.eyeTop[2]">
          </td>
        </tr>
        <tr>
          <td>near</td>
          <td colspan="3"><input v-model.number="config.near"></td>
        </tr>
        <tr>
          <td>far</td>
          <td colspan="3"><input v-model.number="config.far"></td>
        </tr>
        <tr>
          <th>Material</th>
          <th colspan="3"></th>
        </tr>
        <tr>
          <td>gloss</td>
          <td colspan="3">
            <input v-model.number="config.gloss">
            <input type="range" min="1" max="100" step=".1" v-model.number="config.gloss">
          </td>
        </tr>
        </tbody>
      </table>

    </div>
  </div>
</template>

<script>

import {renderDemo} from '../soft-renderer/main';
import {quat, vec3} from 'gl-matrix';

async function render(context, logTime = true) {
  if (logTime) {
    console.time('render cost');
  }
  await renderDemo(
      context,
      this.config.scale,
      this.config.rotate,
      this.config.translate,

      this.config.eyePos,
      this.config.eyeCenter,
      this.config.eyeTop,

      this.config.fovY,
      this.config.near,
      this.config.far,
      null,
      this.config.gloss,
  );
  if (logTime) {
    console.timeEnd('render cost');
  }
}

export default {
  name: 'm-canvas',
  data() {
    return {
      context: null,
      config: {
        scale: [1, 1, 1],
        rotate: [0, 0, 0],
        translate: [0, 0, 0],
        eyePos: [0, 0, 0],
        eyeCenter: [0, 0, 0],
        eyeTop: [0, 0, -1],
        fovY: Math.PI / 3,
        near: 0.1,
        far: 100,
        gloss: 10,
      },
      eyeEuler: [0, 0, 0],
    };
  },
  mounted() {
    let canvas = this.$refs.canvas;
    console.log(canvas);
    let context = canvas.getContext('2d');
    this.context = context;
    this.movCam();
    this.refresh();
  },
  methods: {
    refresh() {
      render.call(this, this.context);
    },
    movCam() {
      const [x, y, z] = this.eyeEuler;
      let q = quat.create();
      quat.fromEuler(q, x, y, z);
      let l = quat.create();
      let len = 5;
      vec3.transformQuat(l, [1, 1, 1], q);
      const [xp, yp, zp] = this.config.eyeCenter;
      const [xt, yt, zt] = l;
      this.config.eyePos = [
        xp + xt * len,
        yp + yt * len,
        zp + zt * len,
      ];
    },
  },
  watch: {
    'config': {
      handler() {
        this.refresh();
      },
      deep: true,
    },
    'eyeEuler': {
      deep: true,
      handler() {
        this.movCam();
      },
    },
  },
};
</script>

<style scoped>
.TransformNCamera input {
  width: 100px;
}
</style>
